package shader

import (
	"github.com/go-gl/gl/v2.1/gl"
)
type Program struct{
	program uint32
	totalAttributeNum,attributeNumStep int32
}

func NewProgram(vertexShader,fragmentShader uint32) *Program{
	program := gl.CreateProgram()
	gl.AttachShader(program,vertexShader)
	gl.AttachShader(program,fragmentShader)
	gl.LinkProgram(program)
	return &Program{program:program}
}

func(s Program)Use() Program{
	gl.UseProgram(s.program)
	return s
}

func(s Program)AttachShader(shader uint32){
	gl.AttachShader(s.program, shader)
}

func (s Program)GetProgram() uint32{
	return s.program
}

func (s Program)GetUniformLocation(str string) int32{
	return gl.GetUniformLocation(s.program,gl.Str(str+"\x00"))
}

func (s Program) Bind1i(str string,v0 int32){
	gl.Uniform1i(s.GetUniformLocation(str), v0);
}

func (s Program) Bind1f(str string,v0 float32){
	gl.Uniform1f(s.GetUniformLocation(str), v0);
}

func (s Program) Bind3f(str string, v0 float32, v1 float32, v2 float32){
	gl.Uniform3f(s.GetUniformLocation(str),v0,v1,v2)
}

func (s Program) Bind3fv(str string,count int32,value *float32){
	gl.Uniform3fv(s.GetUniformLocation(str),1,value)
}

func (s Program) Bind4fv(str string,count int32,transpose bool,value *float32){
	gl.UniformMatrix4fv(s.GetUniformLocation(str),1,false,value)
}

func (s *Program) SetTotalAttributeNum(totalAttributeNum int32){
	s.totalAttributeNum = totalAttributeNum
	s.attributeNumStep = 0
}

func (s *Program) BindAttribute(str string,size int32){
	attr := uint32(gl.GetAttribLocation(s.program, gl.Str(str+"\x00")))
	gl.VertexAttribPointer(attr, size, gl.FLOAT, false, s.totalAttributeNum*4, gl.PtrOffset(int(s.attributeNumStep)*4))
	gl.EnableVertexAttribArray(attr)
	s.attributeNumStep += size
}